#include <iostream>
using namespace std;

class Rational {
    int top;
    int bottom;

public: 

    

    
    void divTopBottom() {
        int divisor = gcd(abs(top), bottom);
        top /= divisor;
        bottom /= divisor;
    }
    
    void normalize() {
        if (bottom < 0) {
            bottom = -bottom;
            top = -top;   
        }
    }
    
    Rational(int top):top(top), bottom(1) {}
    
    Rational(int top, int bottom):
        top(top),
        bottom(bottom) {
        normalize();
        divTopBottom();
    }
    
    Rational & operator +=(const Rational & r) {
        top = top * r.bottom + r.top * bottom;
        bottom = bottom * r.bottom;
        divTopBottom();
	return *this;
    }
    
    Rational & operator -=(const Rational & r) {
        *this += -r;
        return *this;
    }
    
    
    Rational & operator *=(const Rational & r) {
        top *= r.top;
        bottom *= r.bottom;
        divTopBottom();
	return *this;
    }  
    
    Rational & operator /=(const Rational & r) {
        *this *= r.inv();
	return *this;
    }
    
    Rational inv() const {
        Rational result(*this);
        std::swap(result.top, result.bottom);
        result.normalize();
        return result;
    }
    
    Rational operator -() const {
        Rational result(-top, bottom);
        return result;
    }
    
    bool operator ==(const Rational & r) const {
        return top == r.top && bottom == r.bottom;  
    }
    bool operator <=(const Rational & r) const {
        return !(*this > r);
    }
    bool operator >=(const Rational & r) const {
        return !(*this < r);
    }
    bool operator <(const Rational & r) const {
        return top * r.bottom < r.top * bottom;
    }
    bool operator >(const Rational & r) const {
        return r < *this;
    }
    
    operator double() const {
	return top / (double) bottom;
    }
    
    Rational operator+ (const Rational & r) { 
        Rational result(*this);
        return result += r;
    }
    
    Rational operator- (const Rational & r) {
        Rational result(*this);
        return result -= r;
    }
    
    Rational operator* (const Rational & r) {
        Rational result(*this);
        return result *= r;
    }
    
    Rational operator/ (const Rational & r) {
        Rational result(*this);
        return result /= r;
    }

    static int gcd(int a, int b) {
        if (a == b) {
            return a;    
        } else if (b < a) { 
            return gcd(b, a);        
        } else {
            return gcd(a, b - a);        
        }
    }

};



int main(int argc){
    
    Rational r1(10,3);
    Rational r2(12,4); 
    Rational r3 = r1 + r2;

    cout << r1 << endl;
    cout << r2 << endl;
    cout << r3 << endl;
    
    Rational r4(-3,2);
    Rational r5(3,9);
    Rational r6(8,4);

    Rational r7 = r4 * r5 / r6;

    cout << r4 << endl;
    cout << r5 << endl;
    cout << r6 << endl;
    cout << r7 << endl;

    
    
    int iiii = 0;
    cin >> iiii;
    return 0;

}

